package com.will.txj.aj.security.config.auth;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.will.txj.aj.global.utils.RedisUtil;
import com.will.txj.aj.security.service.AJUserService;
import com.will.txj.aj.security.service.ISysPermService;
import com.will.txj.aj.security.service.ISysRoleService;
import com.will.txj.common.security.AJUser;
import com.will.txj.common.security.SysPerm;
import com.will.txj.common.security.SysRole;
import com.will.txj.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author: wen-yi;
 * @date: 2021/11/26 0:04;
 * @Description: 获取数据库数据
 */
@Slf4j
@Component
public class AJUserDetailsService implements UserDetailsService {
    @Resource
    private AJUserService ajUserService;
    @Resource
    private ISysPermService permService;
    @Resource
    private ISysRoleService roleService;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StringUtil.isEmptyToString(username)) throw new BadCredentialsException("账号或密码错误");
        // 先去redis中获取用户对象
        AJUser user = redisUtil.get("user-"+username,AJUser.class);
        // log.info("redis中用户数据：{}",user);
        if (user==null){
            log.info("创建用户信息: {}",username);
            //1、登录的时候调用该方法 进行：验证用户名、验证凭证
            user = ajUserService.getOne(new LambdaQueryWrapper<AJUser>().eq(AJUser::getUsername, username));
            if (user==null) return null;
            //2、找到该账户的角色、权限 动态添加授权
            ArrayList<GrantedAuthority> authorities = new ArrayList<>();
            List<SysRole> roles = roleService.getRoleListByUsername(username);
            if (roles!=null&&roles.size()>0){
                roles.forEach(r -> {
                    authorities.add(new SimpleGrantedAuthority("ROLE_"+r.getRoleCode()));
                });
            }
            List<SysPerm> permissionList = permService.getPermissionListByUsername(username);
            if (permissionList!=null&&permissionList.size()>0){
                permissionList.forEach(p -> {
                    authorities.add(new SimpleGrantedAuthority(p.getPermTag()));
                });
            }
            user.setAuthorities(authorities);
            boolean flag = redisUtil.set("user-" + username, user, 30, TimeUnit.MINUTES);
            if (!flag)log.error("将用户对象压入redis失败" );
        } else {
            log.info("更新用户的认证时间(默认30分钟): {}",username);
            redisUtil.set("user-"+username, user,30,TimeUnit.MINUTES);
        }
        return user;
    }
}
